package com.example.site_management_p1.service.Impl;
import com.example.site_management_p1.config.SiteRabbitConfig;
import com.example.site_management_p1.service.ISiteService;
import com.pojo.Entity.ChargingStandards;
import com.pojo.Entity.Site;
import com.pojo.Entity.VenueRentalForm;
import com.pojo.dto.ToDate;
import com.pojo.dto.ToER;
import com.pojo.dto.ToSite;
import com.pojo.mapper.ChargingStandardsMapper;
import com.pojo.mapper.DarkRoomMapper;
import com.pojo.mapper.SiteMapper;
import com.pojo.mapper.VenueRentalFormMapper;
import com.pojo.util.Tool;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class SiteServiceImpl implements ISiteService {
    @Autowired
    SiteMapper siteMapper;
    @Autowired
    DarkRoomMapper darkRoomMapper;
    @Autowired
    VenueRentalFormMapper venueRentalFormMapper;
    @Autowired
    ChargingStandardsMapper chargingStandardsMapper;
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    RedissonClient redissonClient;
    @Autowired
    RabbitTemplate rabbitTemplate;
    private static final String SITE_KEY="SITE_KEY_GET:";
    private static final String SITE_LOCK_KEY="SITE_LOCK_KEY:";
    private static final String SITE_PRE_LOCK_KEY="SITE_PRE_LOCK_KEY:";
    @Override
    public List<ToSite> getlsite(Integer page, Integer number) {
        page=(page-1)*number;
        return siteMapper.findByPn(page,number);
    }
    @Override
    public Integer update(Site site, HttpServletRequest httpServletRequest) {
        site.setRID((Integer) redisTemplate.opsForHash().get(httpServletRequest.getHeader("identifying"),"uID"));
        String sky=SITE_KEY+String.valueOf(site.getSID());
        String lsky=SITE_LOCK_KEY+":update"+String.valueOf(site.getSID());
        try {
            return Tool.updateToRedis(site1->siteMapper.update(site1),site,sky,lsky,redisTemplate,redissonClient);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
    @Override
    public Site getsite(Integer sID) {
        String sky=SITE_KEY+String.valueOf(sID);
        String lsky=SITE_LOCK_KEY+String.valueOf(sID);
        Site site= (Site) redisTemplate.opsForValue().get(sky);
        if(site==null) {
            try {
                site = (Site) Tool.putDateToRedis(sID1 -> siteMapper.findBysID(sID1), sID, sky,lsky,new Site(),redisTemplate,redissonClient);
                return site;
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return site;
    }


    @Override
    public Integer insert(Site site, HttpServletRequest httpServletRequest) {
        site.setRID((Integer) redisTemplate.opsForHash().get(httpServletRequest.getHeader("identifying"),"uID"));
        return siteMapper.insert(site);
    }

    @Override
    public List<ToDate> getdelsite(String sDate, Integer sID) {
        SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd");
        Date vDate=null;
        try {
            vDate=ft.parse(sDate);
        }catch (Exception e){
            return null;
        }
        System.out.println(vDate);
        return venueRentalFormMapper.findlByDate(vDate,sID,null,null);
    }

    @Override
    public VenueRentalForm presite(String sBegintime, String sEndtime, String sDate, Integer sID, HttpServletRequest httpServletRequest)  {
        Integer rID=(Integer) redisTemplate.opsForHash().get(httpServletRequest.getHeader("identifying"),"uID");
        SimpleDateFormat ft1 = new SimpleDateFormat("yyyy-MM-dd");
        Date vDate=null;
        if(sBegintime.compareTo(sEndtime)>=0)
            return null;
        String today= new SimpleDateFormat("yyyy-MM-dd HH:mm").format(new Date());
        if(today.compareTo(sDate+" "+sBegintime)>0)
            return null;
        try {
            vDate=ft1.parse(sDate);
        }catch (Exception e){
            return null;
        }
        Integer bk=darkRoomMapper.findbyRD(rID,vDate);
        if (bk==3)
            return null;
        SimpleDateFormat ft = new SimpleDateFormat("HH:mm");
        Date vBegintime =null;
        Date vEndtime   =null;
        try {
             vBegintime = ft.parse(sBegintime);
             vEndtime   =ft.parse(sEndtime);
        }catch (Exception e){
            return null;
        }
        String lsky=SITE_PRE_LOCK_KEY+String.valueOf(sID);
        RLock rLock= redissonClient.getLock(lsky);
       try {
           boolean islock=rLock.tryLock(3,2, TimeUnit.SECONDS);
           if(islock){
               Site site=siteMapper.findBysID(sID);
               List<ToDate>ldt=venueRentalFormMapper.findlByDate(vDate,sID,vBegintime,vEndtime);
               if(ldt.size()>0)
                   return null;
             //  ChargingStandards chargingStandards=chargingStandardsMapper.findBycID(site.getCID());
               Integer vAmountOfMoney=Tool.getMoney(vBegintime,vEndtime,site.getCID());
               VenueRentalForm venueRentalForm=new VenueRentalForm(null,site.getSID(),rID,vBegintime,vEndtime,vDate,vAmountOfMoney,0);
               Integer count=venueRentalFormMapper.insert(venueRentalForm);
               if(count==1){
                   rabbitTemplate.convertAndSend(SiteRabbitConfig.EXCHANGE_NAME,
                           SiteRabbitConfig.ROUTINGKEY_SITE,String.valueOf(venueRentalForm.getVID()));
               }
               return count==1?venueRentalForm:null;
           }
       }catch (Exception e){
       }finally {
           if (rLock.isLocked()) { // 是否还是锁定状态
               if (rLock.isHeldByCurrentThread()) { // 时候是当前执行线程的锁
                   rLock.unlock(); // 释放锁
               }
           }
       }
       return null;
    }

    @Override
    public VenueRentalForm Cpresite(String sBegintime, String sEndtime, String sDate, Integer sID, HttpServletRequest httpServletRequest) {
        SimpleDateFormat ft1 = new SimpleDateFormat("yyyy-MM-dd");
        Date vDate=null;
        if(sBegintime.compareTo(sEndtime)>=0)
            return null;
        String today= new SimpleDateFormat("yyyy-MM-dd HH:mm").format(new Date());
        if(today.compareTo(sDate+" "+sBegintime)>0)
            return null;
        try {
            vDate=ft1.parse(sDate);
        }catch (Exception e){
            return null;
        }
        SimpleDateFormat ft = new SimpleDateFormat("HH:mm");
        Date vBegintime =null;
        Date vEndtime   =null;
        try {
            vBegintime = ft.parse(sBegintime);
            vEndtime   =ft.parse(sEndtime);
        }catch (Exception e){
            return null;
        }
        String lsky=SITE_PRE_LOCK_KEY+String.valueOf(sID);
        RLock rLock= redissonClient.getLock(lsky);
        try {
            boolean islock=rLock.tryLock(3,2, TimeUnit.SECONDS);
            if(islock){
                Site site=siteMapper.findBysID(sID);
                List<ToDate>ldt=venueRentalFormMapper.findlByDate(vDate,sID,vBegintime,vEndtime);
                if(ldt.size()>0)
                    return null;
                Integer rID=(Integer) redisTemplate.opsForHash().get(httpServletRequest.getHeader("identifying"),"uID");
                Integer vAmountOfMoney=Tool.getMoney(vBegintime,vEndtime,site.getCID());
                VenueRentalForm venueRentalForm=new VenueRentalForm(null,site.getSID(),rID,vBegintime,vEndtime,vDate,vAmountOfMoney,1);
                Integer count=venueRentalFormMapper.insert(venueRentalForm);
                return count==1?venueRentalForm:null;
            }
        }catch (Exception e){
        }finally {
            if (rLock.isLocked()) { // 是否还是锁定状态
                if (rLock.isHeldByCurrentThread()) { // 时候是当前执行线程的锁
                    rLock.unlock(); // 释放锁
                }
            }
        }
        return null;
    }

    @Override
    public Integer payment(Integer vID,Integer vPaymentStatus) {
        if (vPaymentStatus==0)
            return 0;
        VenueRentalForm venueRentalForm=venueRentalFormMapper.findByvID(vID);
        if(venueRentalForm.getVPaymentStatus()!=0)
            return 0;
        Integer count=venueRentalFormMapper.update(vID,vPaymentStatus);
        if(count!=null&&count==1&&vPaymentStatus==2){
            darkRoomMapper.insert(venueRentalFormMapper.findByvID(vID).getRID(),new Date());
        }
        return count;
    }

    @Override
    public List<ToER> getAftter(HttpServletRequest httpServletRequest) {
        Integer rID= (Integer) redisTemplate.opsForHash().get(httpServletRequest.getHeader("identifying"),"uID");
        Date vDate=Tool.getDateAfter(new Date(),-7);
        return venueRentalFormMapper.findbyAffter(vDate,rID);
    }

    @Override
    public Integer getsum() {
        return siteMapper.getsum();
    }

    @Override
    public Integer delete(Integer sID) {
        redisTemplate.delete( SITE_KEY+String.valueOf(sID));
        return siteMapper.delete(new Date(),sID);
    }
}
